package com.sxt.bus.utils;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.EnumMap;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

/**
 * 生成二维码
 * 
 * @author LJH
 * 
 */
public class ZXingCodeEncodeUtils {
	// 设置相前的常量
	// 二维码颜色
	private static final int BLACK = 0xFF000000; // #fff #ffffff
	// 二维码背景颜色
	private static final int WHITE = 0xFFFFFFFF;
	// 二维码格式参数
	private static final EnumMap<EncodeHintType, Object> hints = new EnumMap<EncodeHintType, Object>(
			EncodeHintType.class);
	static {
		/*
		 * 二维码的纠错级别(排错率),4个级别： L (7%)、 M (15%)、 Q (25%)、 H (30%)(最高H)
		 * 纠错信息同样存储在二维码中，纠错级别越高，纠错信息占用的空间越多，那么能存储的有用讯息就越少；共有四级； 选择M，扫描速度快。
		 */
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
		// 二维码边界空白大小 1,2,3,4 (4为默认,最大)
		hints.put(EncodeHintType.MARGIN, 1);
		hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
	}

	/**
	 * 生成一个普通的二维保存到相关路径
	 * 
	 * @param text
	 *            二维码的内容
	 * @param width
	 *            宽度
	 * @param height
	 *            高度
	 * @param outPutPath
	 *            输出路径
	 * @param imageType
	 *            图片格式 png gif jpge
	 */
	public static void createZxingCodeNormal(String text, int width,
			int height, String outPutPath, String imageType) {
		try {
			// 1、生成二维码
			BitMatrix encode = new MultiFormatWriter().encode(text,
					BarcodeFormat.QR_CODE, width, height, hints);
			// 2、获取二维码宽高
			int codeWidth = encode.getWidth();
			int codeHeight = encode.getHeight();

			// 3、将二维码放入缓冲流
			BufferedImage image = new BufferedImage(codeWidth, codeHeight,
					BufferedImage.TYPE_INT_RGB);
			for (int i = 0; i < codeWidth; i++) {
				for (int j = 0; j < codeHeight; j++) {
					// 4、循环将二维码内容定入图片
					image.setRGB(i, j, encode.get(i, j) ? BLACK : WHITE);
				}
			}
			// 4，构造图片输出地址
			File outPutImage = new File(outPutPath);
			// 如果图片不存在创建图片
			if (!outPutImage.exists()) {
				outPutImage.createNewFile();
			}
			// 5、将二维码写入图片
			ImageIO.write(image, imageType, outPutImage);
		} catch (WriterException e) {
			e.printStackTrace();
			System.out.println("二维码生成失败");
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("生成二维码图片失败");
		}
	}

	/**
	 * 生成一个普通的二维返回图片对象
	 * 
	 * @param text
	 *            二维码的内容
	 * @param width
	 *            宽度
	 * @param height
	 *            高度
	 * @param outPutPath
	 *            输出路径
	 * @param imageType
	 *            图片格式 png gif jpge
	 */
	public static BufferedImage createZxingCodeBufferImage(String text,
			int width, int height, String imageType) {
		try {
			// 1、生成二维码
			BitMatrix encode = new MultiFormatWriter().encode(text,
					BarcodeFormat.QR_CODE, width, height, hints);
			// 2、获取二维码宽高
			int codeWidth = encode.getWidth();
			int codeHeight = encode.getHeight();
			// 3、将二维码放入缓冲流
			BufferedImage image = new BufferedImage(codeWidth, codeHeight,
					BufferedImage.TYPE_INT_RGB);
			for (int i = 0; i < codeWidth; i++) {
				for (int j = 0; j < codeHeight; j++) {
					// 4、循环将二维码内容定入图片
					image.setRGB(i, j, encode.get(i, j) ? BLACK : WHITE);
				}
			}
			return image;
		} catch (WriterException e) {
			e.printStackTrace();
			System.out.println("二维码生成失败");
		}
		return null;
	}

	/**
	 * 生成一个带logo的二维返回图片对象
	 * 
	 * @param text
	 *            二维码的内容
	 * @param width
	 *            宽度
	 * @param height
	 *            高度
	 * @param outPutPath
	 *            输出路径
	 * @param imageType
	 *            图片格式 png gif jpge
	 */
	public static BufferedImage createZxingCodeBufferImage_Logo(String text,
			int width, int height, String imageType, InputStream logoStream) {
		// 1,生成二维码的图片
		BufferedImage image = createZxingCodeBufferImage(text, width, height,
				imageType);
		if (null == image) {
			System.out.println("二维码生成失败");
			return null;
		}
		try {
			// 2,得到logo的图片对象
			if (null == logoStream) {
				System.out.println("logo为空");
				return image;
			}
			BufferedImage logo = ImageIO.read(logoStream);

			// 3,得到logo的原始宽高
			int logoOldWidth = logo.getWidth();
			int logoOldHeight = logo.getHeight();
			// 4,得到二维码的宽高
			int codeWidth = image.getWidth();
			int codeHeight = image.getHeight();
			// 5,把二维的宽度除以5得到logo在二维码上面的最大宽高
			int logoMaxWidth = codeWidth / 5;
			int logoMaxHeight = codeHeight / 5;
			// 6,计算出真正的logo的宽高
			int logoWidth = logoOldWidth > logoMaxWidth ? logoMaxWidth
					: logoOldWidth;
			int logoHeight = logoOldHeight > logoMaxHeight ? logoMaxHeight
					: logoOldHeight;

			//7,计算logo的开始位置
			int startX=(codeWidth-logoWidth)/2;
		    int startY=(codeHeight-logoHeight)/2;
			// 8,获取画笔
			Graphics2D g = image.createGraphics();
			//9,画图片
			g.drawImage(logo, startX, startY, logoWidth, logoHeight, null);
			//10,画一个圆角边框
			g.drawRoundRect(startX, startY, logoWidth, logoHeight, 15, 15);
			//11,logo边框大小
			g.setStroke(new BasicStroke(2));
			//12 logo边框颜色
			g.setColor(Color.WHITE);
			g.drawRect(startX, startY, logoWidth, logoHeight);
			//刷新
			g.dispose();
			logo.flush();
			image.flush();
			return image;
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}

	public static void main(String[] args) {
		String text = "老雷";
//		createZxingCodeNormal(text, 300, 300, "D:/laolei.gif", "gif");
		System.out.println("生成成功");

	}

}
